﻿//===============================================================================
// Apolineo Patterns & Practices LeanEngine Framework
//===============================================================================
// Copyright © Apolineo Desenvolvimento de Sistemas Ltda.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================

using System;
using System.Data;
using System.Collections;
using System.Collections.Generic;

using LeanEngine.Data;
using LeanEngine.Extensions;

using LeanEngine.SalesConcept.Entity;

namespace LeanEngine.SalesConcept.Repository
{
    //Classe de acesso a dados
    internal static class ProductRepository
    {
        //Método de atualização do valor em estoque de um produto
        //Foi criado como método de extensão para dar uma melhor semântica ao código
        internal static void UpdateStock(this IEnumerable<Product> productsSolds)
        {
            foreach (Product dto in productsSolds)
            {
                //Aqui usamos o DataCommand (do namespace Data) como qualquer comando ADO.NET
                using (var cmd = new DataCommand())
                {
                    //Na criação da string do comando usamos o Database.Instance.ParameterSymbol
                    //para obter o simbolo de parametro para o banco de dados
                    cmd.CommandText = "UPDATE [Product] SET [QuantityInStock] = @QuantityInStock "
                                    + "WHERE [ProductId] = @ProductId";

                    cmd.Parameters.Add(cmd.NewParameter("QuantityInStock", dto.QuantityInStock));
                    cmd.Parameters.Add(cmd.NewParameter("ProductId", dto.Id));

                    cmd.ExecuteNonQuery();
                }
            }
        }

        //Método de pesquisa de verificação de disponibilidade de produtos em estoque
        //Foi criado como método de extensão para dar uma melhor semântica ao código
        internal static bool HasItensInStock(this Product dto, int quantityNeeded)
        {
            if (dto.Id.IsLessThanEqual(0))
            {
                return false;
            }

            object value = null;
            using (DataCommand cmd = new DataCommand())
            {
                cmd.CommandText = "SELECT p.[QuantityInStock] FROM [Product] p WHERE p.[ProductId] = @ProductId";
                cmd.CommandType = CommandType.Text;

                cmd.Parameters.Add(cmd.NewParameter("ProductId", dto.Id));

                value = cmd.ExecuteScalar();
            }

            if (value.IsNull())
            {
                throw new InvalidOperationException("Product id " + dto.Id.ToString() + " not found.");
            }

            //Aqui utilizamos o método de extensão de conversão do lob (namespace LeanEngine)
            dto.QuantityInStock = value.ToInt32();

            //Aqui utilizamos o método de extensão de verificação do lob (namespace LeanEngine)
            return (dto.QuantityInStock - quantityNeeded).IsGreaterThanEqual(0);
        }
    }
}
